package com.ruoyi.iot.modbus.rtu;

import com.ruoyi.iot.domain.IotMasterConfig;
import com.ruoyi.iot.utils.ModbusCache;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import jssc.SerialPort;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;


/**
 * @description:
 * @author: Howe
 * @create: 2019-12-05 17:42
 */
@Slf4j
public class RTUMasterUtils {

    /**
     * 初始化modbusFactory
     */
    static ModbusFactory modbusFactory;

    static {
        modbusFactory = new ModbusFactory();
    }

    /**
     * @Description: 获取RTUMaster
     * @Param: []
     * @Return: com.serotonin.modbus4j.ModbusMaster
     * @Author: Howe
     * @Date: 2019/12/5 10:19
     */
    public static Map<String, ModbusMaster> getRTUMasterMap() {
        Map<String, ModbusMaster> modbusMasterMap = new HashMap<>();
        Map<String, IotMasterConfig> serialPortMaps = ModbusCache.getIotMasterConfigMap();
        for (Map.Entry<String, IotMasterConfig> serialPortMap : serialPortMaps.entrySet()) {
            String mapKey = serialPortMap.getKey();
            if (ModbusCache.getModbusMaster(mapKey) != null) {
                modbusMasterMap.put(mapKey, ModbusCache.getModbusMaster(mapKey));
                continue;
            }
            IotMasterConfig serialPort = serialPortMap.getValue();
            ModbusMaster master = getRTUMaster(serialPort);
            modbusMasterMap.put(mapKey, master);
        }
        return modbusMasterMap;
    }


    /**
     * @Description: 获取RTUMaster
     * @Param: [serialPort]
     * @Return: com.serotonin.modbus4j.ModbusMaster
     * @Author: Howe
     * @Date: 2020/1/7 11:49
     */
    public static ModbusMaster getRTUMaster(IotMasterConfig masterConfig) {

        int parity = 0;
        switch (masterConfig.getCheckBit()) {
            case "None":
                break;
            case "ODD":
                parity = 1;
                break;
            case "EVEN":
                parity = 2;
                break;
            case "MARK":
                parity = 3;
                break;
            case "SPACE":
                parity = 4;
                break;
        }

        ModbusMaster master = modbusFactory.createRtuMaster(
                new SerialPortWrapperImpl(masterConfig.getSerialPort(),
                        masterConfig.getBaudRate(),
                        masterConfig.getDataBits(),
                        masterConfig.getStopBit(),
                        parity,
                        SerialPort.FLOWCONTROL_NONE,
                        SerialPort.FLOWCONTROL_NONE));

        try {
            master.init();
        } catch (ModbusInitException e) {
            log.error("初始化RTUMaster失败{}", e.getMessage());
        }
        return master;
    }


}
